package org.greatstorm.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import org.greatstorm.cache.GlobalCacheKey;
import org.greatstorm.cache.GlobalCacheManager;
import org.greatstorm.entity.Article;
import org.greatstorm.entity.Category;
import org.greatstorm.entity.EntityObject;
import org.greatstorm.util.Utils;

import com.google.inject.Guice;
import com.google.inject.Singleton;

@Singleton
public class ArticleCategoryMediator {
	private static final Logger log = Logger
			.getLogger(ArticleCategoryMediator.class.getName());
	private GlobalCacheManager gCacheManager;
	private CategoryManager catManager;
	private ArticleManager artManager;
	private ReplyManager rplManager;

	public ArticleCategoryMediator() {
		gCacheManager = Guice.createInjector().getInstance(
				GlobalCacheManager.class);
		catManager = Guice.createInjector().getInstance(CategoryManager.class);
		artManager = Guice.createInjector().getInstance(ArticleManager.class);
		rplManager = Guice.createInjector().getInstance(ReplyManager.class);
	}

	public long getArticleCnt() {
		Long cnt = (Long) gCacheManager
				.getCachedObject(GlobalCacheKey.PAGE_ARTCILE_CNT);
		if (cnt != null) {
			log.info("getArticleCnt: read a article count from cache!");
			return cnt;
		}

		cnt = 0L;

		Map<String, String> categoryMap = new HashMap<String, String>();
		List<EntityObject> list = catManager.getAllCategories();

		for (EntityObject o : list) {
			// notes: in GAE, number extracted from ds is Long type
			long count = (Long) o.get(Category.ARTICLE_COUNT);
			cnt += count;

			String key = o.getKey();
			String val = o.get(Category.CATEGORY_NAME) + " (" + count + ")";
			categoryMap.put(key, val);
		}

		gCacheManager.saveOjbectToCache(GlobalCacheKey.PAGE_ARTCILE_CNT, cnt);
		gCacheManager.saveOjbectToCache(GlobalCacheKey.PAGE_CATEGORY_LIST,
				categoryMap);

		return cnt;
	}

	@SuppressWarnings("unchecked")
	public Map<String, String> getCategroyMap() {
		Map<String, String> categoryMap = (Map<String, String>) gCacheManager
				.getCachedObject(GlobalCacheKey.PAGE_CATEGORY_LIST);

		if (categoryMap == null) {
			categoryMap = new HashMap<String, String>();

			List<EntityObject> list = catManager.getAllCategories();
			for (EntityObject o : list) {
				// notes: in GAE, number extracted from ds is Long type
				long count = (Long) o.get(Category.ARTICLE_COUNT);

				String key = o.getKey();
				String val = o.get(Category.CATEGORY_NAME) + " (" + count + ")";
				categoryMap.put(key, val);
			}

			gCacheManager.saveOjbectToCache(GlobalCacheKey.PAGE_CATEGORY_LIST,
					categoryMap);
		}

		log.info("getCategroyMap: read a CategroyMap from cache!");

		return categoryMap;
	}

	public Map<String, List<String>> getArticleMapByCategory(int pageno,
			String categoryKey) {
		List<EntityObject> ret = artManager.getArticleByCategory(pageno,
				categoryKey);
		Map<String, List<String>> map = new HashMap<String, List<String>>();
		EntityObject category = catManager.getCategoryByKey(categoryKey);
		String catName = (String) category.get(Category.CATEGORY_NAME);

		for (EntityObject o : ret) {
			List<String> artAttr = new ArrayList<String>();
			artAttr.add((String) o.get(Article.ARTICLE_TITLE));
			artAttr.add(Utils.formatDate((Date) o.get(Article.CREATE_DATE),
					Utils.DATE_FORMAT_STR));
			artAttr.add(catName);
			artAttr.add(String.valueOf(o.get(Article.READ_COUNT)));

			List<EntityObject> replies = rplManager.getReplesByArticleKey(o
					.getKey());
			artAttr.add(String.valueOf(replies.size()));

			map.put(o.getKey(), artAttr);
		}

		return map;
	}

	public String getCategoryName(String key) {
		EntityObject category = catManager.getCategoryByKey(key);
		return (String) category.get(Category.CATEGORY_NAME);
	}

	public Map<String, List<String>> getAllArticleMap(Integer pageno) {
		List<EntityObject> ret = artManager.getAllArticle(pageno);
		Map<String, List<String>> map = new HashMap<String, List<String>>();

		for (EntityObject o : ret) {
			List<String> artAttr = new ArrayList<String>();
			artAttr.add((String) o.get(Article.ARTICLE_TITLE));
			artAttr.add(Utils.formatDate((Date) o.get(Article.CREATE_DATE),
					Utils.DATE_FORMAT_STR));
			// get the category
			EntityObject category = catManager.getCategoryByKey((String) o
					.get(Article.CATEGORY_FK));
			String catName = (String) category.get(Category.CATEGORY_NAME);
			artAttr.add(catName);

			artAttr.add(String.valueOf(o.get(Article.READ_COUNT)));

			List<EntityObject> replies = rplManager.getReplesByArticleKey(o
					.getKey());
			artAttr.add(String.valueOf(replies.size()));

			map.put(o.getKey(), artAttr);
		}

		return map;
	}

	public Map<String, String> getCategroyMapWithoutCount() {
		Map<String, String> categoryMap = new HashMap<String, String>();

		List<EntityObject> list = catManager.getAllCategories();
		for (EntityObject o : list) {

			String key = o.getKey();
			String val = (String) o.get(Category.CATEGORY_NAME);
			categoryMap.put(key, val);
		}

		return categoryMap;
	}

	public void addNewArticle(String categoryKey, String title, String content,
			List<String> tagList) {
		artManager.addArticle(categoryKey, title, content, tagList);
	}

	public String deleteArticle(String key) {
		String articleName = artManager.deleteArticleByKey(key);

		return articleName;
	}

	public void stickyArticle(String key, int optVal) {
		artManager.stickyArticle(key, optVal);
	}

	public Map<String, Object> getArticleMapByKey(String key) {
		Map<String, Object> ret = artManager.getArticleById(key);

		return ret;
	}

	public void editArticle(String articleKey, String categoryKey,
			String title, String content, List<String> tagList) {
		artManager
				.editArticle(articleKey, categoryKey, title, content, tagList);
	}
}
